package cn.iocoder.yudao.module.system.service.equivalentscorerank;

import cn.iocoder.yudao.module.system.dal.dataobject.equivalentscorerank.EquivalentScoreRankDO;
import cn.iocoder.yudao.module.system.dal.dataobject.equivalentscorerank.EquivalentScoreDetailDO;

import javax.validation.Valid;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;

/**
 * 等效位次和等效分 Service 接口
 *
 * @author 芋道源码
 */
public interface EquivalentScoreRankService {

    /**
     * 计算学生的等效位次和等效分
     *
     * @param examId 考试ID
     * @param studentId 学生ID
     * @param controlLineId 特控线ID
     * @return 等效位次和等效分记录
     */
    EquivalentScoreRankDO calculateEquivalentScoreRank(Long examId, Long studentId, Long controlLineId);

    /**
     * 批量计算班级学生的等效位次和等效分
     *
     * @param examId 考试ID
     * @param controlLineId 特控线ID
     * @return 计算成功的记录数
     */
    int batchCalculateEquivalentScoreRank(Long examId, Long controlLineId);

    /**
     * 根据学生成绩、特控线和省控线计算等效分
     *
     * @param originalScore 学生原始成绩
     * @param controlLineScore 特控线分数
     * @param provinceControlLineScore 省控线分数
     * @return 等效分
     */
    BigDecimal calculateEquivalentScore(BigDecimal originalScore, BigDecimal controlLineScore, BigDecimal provinceControlLineScore);

    /**
     * 根据等效分计算等效位次
     *
     * @param equivalentScore 等效分
     * @param province 省份
     * @param year 年份
     * @param examType 考试类型
     * @return 等效位次
     */
    Integer calculateEquivalentRank(BigDecimal equivalentScore, String province, Integer year, String examType);

    /**
     * 获取指定省份和考试类型的省控线数据
     *
     * @param province 省份
     * @param examType 考试类型
     * @param years 年份列表
     * @return 省控线数据映射 (年份 -> 分数)
     */
    Map<Integer, BigDecimal> getProvinceControlLines(String province, String examType, List<Integer> years);

    /**
     * 获取学生的等效位次和等效分记录
     *
     * @param examId 考试ID
     * @param studentId 学生ID
     * @return 等效位次和等效分记录
     */
    EquivalentScoreRankDO getEquivalentScoreRank(Long examId, Long studentId);

    /**
     * 获取学生的等效位次和等效分记录（指定特控线）
     *
     * @param examId 考试ID
     * @param studentId 学生ID
     * @param controlLineId 特控线ID
     * @return 等效位次和等效分记录
     */
    EquivalentScoreRankDO getEquivalentScoreRank(Long examId, Long studentId, Long controlLineId);

    /**
     * 获取学生的所有等效位次和等效分记录
     *
     * @param studentId 学生ID
     * @return 等效位次和等效分记录列表
     */
    List<EquivalentScoreRankDO> getEquivalentScoreRanksByStudentId(Long studentId);

    /**
     * 获取考试的所有等效位次和等效分记录
     *
     * @param examId 考试ID
     * @return 等效位次和等效分记录列表
     */
    List<EquivalentScoreRankDO> getEquivalentScoreRanksByExamId(Long examId);

    /**
     * 创建等效位次和等效分记录
     *
     * @param equivalentScoreRank 等效位次和等效分记录
     * @return 记录ID
     */
    Long createEquivalentScoreRank(@Valid EquivalentScoreRankDO equivalentScoreRank);

    /**
     * 更新等效位次和等效分记录
     *
     * @param equivalentScoreRank 等效位次和等效分记录
     */
    void updateEquivalentScoreRank(@Valid EquivalentScoreRankDO equivalentScoreRank);

    /**
     * 删除等效位次和等效分记录
     *
     * @param id 记录ID
     */
    void deleteEquivalentScoreRank(Long id);

    /**
     * 获取等效分数详情列表
     *
     * @param equivalentScoreRankId 等效分数排名记录ID
     * @return 详情列表
     */
    List<EquivalentScoreDetailDO> getEquivalentScoreDetails(Long equivalentScoreRankId);

    /**
     * 获取指定年份的等效分数详情
     *
     * @param equivalentScoreRankId 等效分数排名记录ID
     * @param year 年份
     * @return 详情记录
     */
    EquivalentScoreDetailDO getEquivalentScoreDetail(Long equivalentScoreRankId, Integer year);

    /**
     * 批量保存等效分数详情
     *
     * @param equivalentScoreRankId 等效分数排名记录ID
     * @param details 详情列表
     */
    void saveEquivalentScoreDetails(Long equivalentScoreRankId, List<EquivalentScoreDetailDO> details);

    /**
     * 删除等效分数详情
     *
     * @param equivalentScoreRankId 等效分数排名记录ID
     */
    void deleteEquivalentScoreDetails(Long equivalentScoreRankId);

    /**
     * 删除考试的所有等效位次和等效分记录
     *
     * @param examId 考试ID
     * @return 删除的记录数
     */
    int deleteEquivalentScoreRanksByExamId(Long examId);

    /**
     * 删除学生的所有等效位次和等效分记录
     *
     * @param studentId 学生ID
     * @return 删除的记录数
     */
    int deleteEquivalentScoreRanksByStudentId(Long studentId);

    /**
     * 重新计算等效位次和等效分（当省控线数据更新时）
     *
     * @param province 省份
     * @param examType 考试类型
     * @return 重新计算的记录数
     */
    int recalculateEquivalentScoreRank(String province, String examType);

    /**
     * 验证等效位次和等效分计算的前置条件
     *
     * @param examId 考试ID
     * @param studentId 学生ID
     * @param controlLineId 特控线ID
     * @return 验证结果消息，null表示验证通过
     */
    String validateCalculationPreconditions(Long examId, Long studentId, Long controlLineId);

    /**
     * 根据用户输入的参数直接计算等效位次和等效分
     *
     * @param province 省份
     * @param examType 选科类型（如：物理类、历史类）
     * @param examScore 考试分数
     * @param controlLineScore 特控线分数
     * @return 包含2025、2024、2023年等效分和等效位次的结果
     */
    Map<Integer, Map<String, Object>> calculateEquivalentScoreRankByInput(String province, String examType, BigDecimal examScore, BigDecimal controlLineScore);

}